package com.apkfuns.jsbridge.view.slice;


import com.apkfuns.jsbridge.ResourceTable;
import com.apkfuns.jsbridge.util.CameraUtil;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.Component;
import ohos.agp.components.Image;
import ohos.agp.components.surfaceprovider.SurfaceProvider;
import ohos.agp.graphics.Surface;
import ohos.agp.graphics.SurfaceOps;
import ohos.agp.utils.Rect;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.media.camera.CameraKit;
import ohos.media.camera.device.Camera;
import ohos.media.camera.device.CameraConfig;
import ohos.media.camera.device.CameraStateCallback;
import ohos.media.camera.device.FrameConfig;
import ohos.media.camera.params.Metadata;
import ohos.media.image.ImageReceiver;
import ohos.media.image.PixelMap;
import ohos.media.image.common.ImageFormat;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Optional;

public class TakePictureAbilitySlice extends AbilitySlice{

    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "TakePictureAbilitySlice");
    private EventHandler cameraEventHandler;
    private static final String TAG = "TakePictureAbilitySlice";
    private SurfaceProvider cameraPreview;
    private Image imgPicture;
    private Camera cameraDevice;


    private String imagePath;
    // 定义生成图片文件名


    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_take_picture);
        getWindow().setTransparent(true);
        getWindow().setBackgroundColor(new RgbColor(0xffffffff));


        imagePath = intent.getStringParam("imagePath");

        HiLog.info(LABEL, "TakePictureAbilitySlice intent imageUri %{public}s", imagePath);


        imgPicture = (Image) findComponentById(ResourceTable.Id_preview_picture);
        cameraPreview = (SurfaceProvider) findComponentById(ResourceTable.Id_camera_preview);
        cameraPreview.pinToZTop(false);
        findComponentById(ResourceTable.Id_btn_take_picture).setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                capture();
            }
        });

        //PixelMap pm = CameraUtil.firstImagePixelMap(getContext());
        //imgPicture.setPixelMap(Optional.ofNullable(pm).get());

        cameraPreview.getSurfaceOps().get().addCallback(new SurfaceCallBack());
        cameraEventHandler = new EventHandler(EventRunner.create("TakePictureAbilitySlice"));
        takePictureInit();
    }





    private void capture() {
        // 获取拍照配置模板
        FrameConfig.Builder framePictureConfigBuilder = cameraDevice.getFrameConfigBuilder(Camera.FrameConfigType.FRAME_CONFIG_PICTURE);
        // 配置拍照Surface
        framePictureConfigBuilder.addSurface(imageReceiver.getRecevingSurface());
        // 配置拍照其他参数
        framePictureConfigBuilder.setImageRotation(90);

        // 启动单帧捕获(拍照)
        cameraDevice.triggerSingleCapture(framePictureConfigBuilder.build());

    }

    private void openCamera() {
        CameraKit cameraKit = CameraKit.getInstance(TakePictureAbilitySlice.this);
        if (cameraKit == null){
            HiLog.info(LABEL,"获取cameraKit失败");
            terminateAbility();
        }
        String[] cameraIds = cameraKit.getCameraIds();
        String cameraId = null;
        int length = cameraIds.length;
        if (length == 0){
            HiLog.info(LABEL, "cameraIds size is 0");
            terminateAbility();
        }
//        else if (length >=2){
//            cameraId = cameraIds[1];
//        }else {
//            cameraId = cameraIds[0];
//        }
        cameraId = cameraIds[0];
        // 相机创建和相机运行时的回调
        CameraStateCallbackImpl cameraStateCallback = new CameraStateCallbackImpl();
        cameraKit.createCamera(cameraId,cameraStateCallback,cameraEventHandler);
    }

    // 图像帧数据接收处理对象
    private ImageReceiver imageReceiver;


    // 单帧捕获生成图像回调Listener
    private final ImageReceiver.IImageArrivalListener imageArrivalListener = new ImageReceiver.IImageArrivalListener() {
        @Override
        public void onImageArrival(ImageReceiver i) {
            HiLog.info(LABEL, "onImageArrival ---------------------------------");
            File myFile = new File(imagePath);//imagePath new File(picturePath, pictureName); // 创建图片文件
            ImageSaver imageSaver = new ImageSaver(i.readNextImage(), myFile); // 创建一个读写线程任务用于保存图片
            cameraEventHandler.postTask(imageSaver); // 执行读写线程任务生成图片
        }
    };

    private void takePictureInit() {
        imageReceiver = ImageReceiver.create(720,720, ImageFormat.JPEG, 1); // 创建ImageReceiver对象，注意creat函数中宽度要大于高度；5为最大支持的图像数，请根据实际设置。
        imageReceiver.setImageArrivalListener(imageArrivalListener);
    }

    private class SurfaceCallBack implements SurfaceOps.Callback{

        @Override
        public void surfaceCreated(SurfaceOps surfaceOps) {
            openCamera();
        }

        @Override
        public void surfaceChanged(SurfaceOps surfaceOps, int i, int i1, int i2) {

        }

        @Override
        public void surfaceDestroyed(SurfaceOps surfaceOps) {

        }
    }

    private final class CameraStateCallbackImpl extends CameraStateCallback {

        private Surface previewSurface;

        @Override
        public void onCreated(Camera camera) {
            // 创建相机设备
            previewSurface = cameraPreview.getSurfaceOps().get().getSurface();

            CameraConfig.Builder cameraConfigBuilder = camera.getCameraConfigBuilder();
            if (cameraConfigBuilder == null) {
                HiLog.info(LABEL, "onCreated cameraConfigBuilder is null");
                return;
            }
            // 配置预览的Surface
            cameraConfigBuilder.addSurface(previewSurface);
            // 配置拍照的Surface
            cameraConfigBuilder.addSurface(imageReceiver.getRecevingSurface());
            try {
                // 相机设备配置
                camera.configure(cameraConfigBuilder.build());
            } catch (IllegalArgumentException e) {
                HiLog.info(LABEL, "Argument Exception");
            } catch (IllegalStateException e) {
                HiLog.info(LABEL, "State Exception");
            }
        }

        @Override
        public void onConfigured(Camera camera) {
            // 获取预览配置模板
            FrameConfig.Builder framePreviewConfigBuilder = camera.getFrameConfigBuilder(Camera.FrameConfigType.FRAME_CONFIG_PREVIEW);
            // 配置预览Surface
            framePreviewConfigBuilder.addSurface(previewSurface);
            framePreviewConfigBuilder.setAeMode(Metadata.AfMode.AF_MODE_CONTINUOUS,new Rect());
            // 启动循环帧捕获
            camera.triggerLoopingCapture(framePreviewConfigBuilder.build());


            cameraDevice = camera;

        }

        @Override
        public void onPartialConfigured(Camera camera) {
            // 当使用了addDeferredSurfaceSize配置了相机，会接到此回调
        }

        @Override
        public void onReleased(Camera camera) {
            // 释放相机设备
            if (camera != null){
                camera.release();
            }
        }
    }

    // 保存图片, 图片数据读写，及图像生成见run方法
    class ImageSaver implements Runnable {
        private final ohos.media.image.Image myImage;
        private final File myFile;

        ImageSaver(ohos.media.image.Image image, File file) {
            myImage = image;
            myFile = file;
        }

        @Override
        public void run() {

            ohos.media.image.Image.Component component = myImage.getComponent(ImageFormat.ComponentType.JPEG);
            byte[] bytes = new byte[component.remaining()];
            component.read(bytes);
            FileOutputStream output = null;
          //  component.getBuffer()
            try {
                output = new FileOutputStream(myFile);
                output.write(bytes); // 写图像数据
                HiLog.info(LABEL, "bytes.length------------------"+bytes.length);
                output.flush();
            } catch (IOException e) {
                HiLog.info(LABEL, "save picture occur exception!"+e.getLocalizedMessage());
            } finally {
                myImage.release();
                if (output != null) {
                    try {
                        output.close(); // 关闭流
                    } catch (IOException e) {
                        HiLog.info(LABEL,  "image release occur exception!");
                    }
                }
            }



                PixelMap pm = CameraUtil.getPixelMapByPath(imagePath,1);
//                PixelMap pm = CameraUtil.firstImagePixelMap(getContext());
                getUITaskDispatcher().asyncDispatch(new Runnable() {
                    @Override
                    public void run() {
                        imgPicture.setPixelMap(Optional.ofNullable(pm).get());
                    }
                });

        }
    }




}


